home *** CD-ROM | disk | FTP | other *** search
- /* This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Synched up with: Not in FSF. */
-
- #ifndef _XEMACS_EXTENTS_H_
- #define _XEMACS_EXTENTS_H_
-
- DECLARE_LRECORD (extent, struct extent);
- #define XEXTENT(x) XRECORD (x, extent, struct extent)
- #define XSETEXTENT(x, p) XSETRECORD (x, p, extent)
- #define EXTENTP(x) RECORDP (x, extent)
- #define CHECK_EXTENT(x, i) CHECK_RECORD (x, extent)
-
- struct extent
- {
- struct lrecord_header lheader;
-
- Memind start;
- Memind end;
- Lisp_Object object; /* A buffer, string, Qnil (extent detached from no
- buffer), Qt (destroyed extent) */
-
- /* Extent properties are conceptually a plist, but the most common
- props are implemented as bits instead of conses.
- */
- struct
- {
- Lisp_Object face;
-
- /* These flags are simply an optimization for common boolean properties
- which go onto the extent's property list. Any of them would work if
- done in the normal way, but the space savings of doing these in this
- way is significant. Note that if you add a flag, there are numerous
- places in extents.c that need to know about it.
-
- Another consideration is that some of these properties are accessed
- during redisplay, so it's good for access to them to be fast (a bit
- reference instead of a search down a plist).
-
- `begin_glyph_layout' and `end_glyph_layout' are unusual in
- that they have 4 states instead of 2.
-
- Other special extent properties are stored in an auxiliary
- structure that sits at the beginning of the plist. The has_aux
- flag indicates whether this structure exists. The has_parent
- flag is an optimization indicating whether the extent has a parent
- (this could also be determined by looking in the aux structure). */
-
- unsigned int begin_glyph_layout :2; /* 2 text, margins, or whitespace */
- unsigned int end_glyph_layout :2; /* 4 text, margins, or whitespace */
- unsigned int has_parent : 1; /* 5 extent has a parent */
- unsigned int has_aux : 1; /* 6 extent has an aux. structure */
- unsigned int start_open : 1; /* 7 insertion behavior at start */
- unsigned int end_open : 1; /* 8 insertion behavior at end */
- unsigned int read_only : 1; /* 9 text under extent is read-only */
- unsigned int highlight : 1; /* 10 mouse motion highlights it */
- unsigned int unique : 1; /* 11 there may be only one attached */
- unsigned int duplicable : 1; /* 12 copied to strings by kill/undo */
- unsigned int invisible : 1; /* 13 whether covered text is visible */
- unsigned int intangible : 1; /* 14 unimplemented */
- unsigned int detachable : 1; /* 15 extent detaches if text deleted */
- unsigned int internal : 1; /* 16 used by map-extents etc. */
- /* --- Adding more flags will cause the extent struct grow by another
- word. It's not clear that this would make a difference, however,
- because on 32-bit machines things tend to get allocated in chunks
- of 4 bytes. */
- } flags;
- /* The plist may have an auxiliary structure as its first element */
- Lisp_Object plist;
- };
-
- typedef struct extent *EXTENT;
-
- /* Basic properties of an extent (not affected by the extent's parent) */
- #define extent_object(e) ((e)->object)
- #define extent_start(e) ((e)->start + 0)
- #define extent_end(e) ((e)->end + 0)
- #define set_extent_start(e, val) ((e)->start = (val))
- #define set_extent_end(e, val) ((e)->end = (val))
- #define extent_endpoint(e, endp) ((endp) ? extent_end (e) : extent_start (e))
- #define set_extent_endpoint(e, val, endp) \
- ((endp) ? set_extent_end (e, val) : set_extent_start (e, val))
- #define extent_detached_p(e) (extent_start (e) == 0)
-
- /* the layouts for glyphs (extent->flags.glyph_layout). Must fit in 2 bits. */
- #define GL_TEXT 0
- #define GL_OUTSIDE_MARGIN 1
- #define GL_INSIDE_MARGIN 2
- #define GL_WHITESPACE 3
-
- /* Additional information that may be present in an extent. The idea is
- that fast access is provided to this information, but since (hopefully)
- most extents won't have this set on them, we usually don't need to
- have this structure around and thus the size of an extent is smaller. */
-
- struct extent_auxiliary
- {
- struct lcrecord_header header;
-
- Lisp_Object begin_glyph;
- Lisp_Object end_glyph;
- Lisp_Object parent;
- Lisp_Object children; /* a list */
- int priority;
- };
-
- extern struct extent_auxiliary extent_auxiliary_defaults;
-
- DECLARE_LRECORD (extent_auxiliary, struct extent_auxiliary);
- #define XEXTENT_AUXILIARY(x) \
- XRECORD (x, extent_auxiliary, struct extent_auxiliary)
- #define XSETEXTENT_AUXILIARY(x, p) XSETRECORD (x, p, extent_auxiliary)
- #define EXTENT_AUXILIARYP(x) RECORDP (x, extent_auxiliary)
- #define CHECK_EXTENT_AUXILIARY(x, i) CHECK_RECORD (x, extent_auxiliary)
-
- /* Note that we take pains in all the macros below never to evaluate
- the extent argument more than once. This may not be necessary
- but is much less likely to introduce subtle bugs. */
-
- MAC_DECLARE_EXTERN (EXTENT, mactemp_ancestor_extent)
- MAC_DECLARE_EXTERN (EXTENT, mactemp_aux_extent)
- MAC_DECLARE_EXTERN (EXTENT, mactemp_plist_extent)
- MAC_DECLARE_EXTERN (EXTENT, mactemp_ensure_extent)
- MAC_DECLARE_EXTERN (EXTENT, mactemp_set_extent)
-
- /* extent_ancestor() chases all the parent links until there aren't any
- more. extent_ancestor_1() does the same thing but it a function;
- the following macro optimizes the most common case. */
-
- #define extent_ancestor(e) \
- MAC_BEGIN \
- MAC_DECLARE (EXTENT, mactemp_ancestor_extent, e) \
- (mactemp_ancestor_extent->flags.has_parent ? \
- extent_ancestor_1 (mactemp_ancestor_extent) : \
- mactemp_ancestor_extent) \
- MAC_END
-
- /* a "normal" field is one that is stored in the `struct flags' structure
- in an extent. an "aux" field is one that is stored in the extent's
- auxiliary structure.
-
- The functions below that have `extent_ancestor' in their name operate
- on an extent directly (ignoring its parent), and should normally
- only be used on extents known not to have a parent. The other
- versions chase down any parent links. */
-
- #define extent_ancestor_normal_field(e, field) ((e)->flags.field)
-
- #define extent_ancestor_aux_field(e, field) \
- MAC_BEGIN \
- MAC_DECLARE (EXTENT, mactemp_aux_extent, e) \
- (mactemp_aux_extent->flags.has_aux ? \
- XEXTENT_AUXILIARY (XCONS (mactemp_aux_extent->plist)->car)->field \
- : extent_auxiliary_defaults.field) \
- MAC_END
-
- #define extent_normal_field(e, field) \
- extent_ancestor_normal_field (extent_ancestor (e), field)
-
- #define extent_aux_field(e, field) \
- extent_ancestor_aux_field (extent_ancestor (e), field)
-
- #define ensure_extent_has_aux_struct(e) \
- MAC_BEGIN \
- MAC_DECLARE (EXTENT, mactemp_ensure_extent, e) \
- (mactemp_ensure_extent->flags.has_aux ? (void) 0 : \
- allocate_extent_aux_struct (mactemp_ensure_extent)) \
- MAC_END
-
- #define set_extent_ancestor_aux_field(e, field, value) \
- MAC_BEGIN \
- MAC_DECLARE (EXTENT, mactemp_set_extent, e) \
- ensure_extent_has_aux_struct (mactemp_set_extent) \
- MAC_SEP \
- XEXTENT_AUXILIARY (XCONS (mactemp_set_extent->plist)->car)->field = \
- (value) \
- MAC_END
-
- #define set_extent_ancestor_normal_field(e, field, value) \
- extent_ancestor_normal_field (e, field) = (value)
-
- #define set_extent_aux_field(e, field, value) \
- set_extent_ancestor_aux_field (extent_ancestor (e), field, value)
-
- #define set_extent_normal_field(e, field, value) \
- set_extent_ancestor_normal_field (extent_ancestor (e), field, value)
-
- /* The `parent' and `children' fields are not affected by any
- parent links. We don't provide any settors for these fields
- because they need special handling and it's cleaner just to
- do this in the particular functions that need to do this. */
-
- #define extent_parent(e) extent_ancestor_aux_field (e, parent)
- #define extent_children(e) extent_ancestor_aux_field (e, children)
-
- #define extent_begin_glyph(e) extent_aux_field (e, begin_glyph)
- #define extent_end_glyph(e) extent_aux_field (e, end_glyph)
- #define extent_priority(e) extent_aux_field (e, priority)
-
- #define set_extent_begin_glyph(e, value) \
- set_extent_aux_field (e, begin_glyph, value)
- #define set_extent_end_glyph(e, value) \
- set_extent_aux_field (e, end_glyph, value)
- #define set_extent_priority(e, value) \
- set_extent_aux_field (e, priority, value)
-
- #define extent_face(e) extent_normal_field (e, face)
- #define extent_begin_glyph_layout(e) extent_normal_field (e, begin_glyph_layout)
- #define extent_end_glyph_layout(e) extent_normal_field (e, end_glyph_layout)
- #define extent_start_open_p(e) extent_normal_field (e, start_open)
- #define extent_end_open_p(e) extent_normal_field (e, end_open)
- #define extent_read_only_p(e) extent_normal_field (e, read_only)
- #define extent_highlight_p(e) extent_normal_field (e, highlight)
- #define extent_unique_p(e) extent_normal_field (e, unique)
- #define extent_duplicable_p(e) extent_normal_field (e, duplicable)
- #define extent_invisible_p(e) extent_normal_field (e, invisible)
- #define extent_intangible_p(e) extent_normal_field (e, intangible)
- #define extent_detachable_p(e) extent_normal_field (e, detachable)
- #define extent_internal_p(e) extent_normal_field (e, internal)
-
- #define extent_ancestor_plist_addr(e) \
- MAC_BEGIN \
- MAC_DECLARE (EXTENT, mactemp_plist_extent, e) \
- (mactemp_plist_extent->flags.has_aux ? \
- &XCONS (mactemp_plist_extent->plist)->cdr : \
- &mactemp_plist_extent->plist) \
- MAC_END
- #define extent_ancestor_plist(e) (*extent_ancestor_plist_addr (e))
-
- #define extent_plist_addr(e) extent_ancestor_plist_addr (extent_ancestor (e))
- #define extent_plist(e) extent_ancestor_plist (extent_ancestor (e))
-
- /* flags for map_extents() and friends */
- #define ME_END_CLOSED (1 << 0)
- #define ME_START_OPEN (1 << 1)
- #define ME_ALL_EXTENTS_CLOSED (1 << 2)
- #define ME_ALL_EXTENTS_OPEN (2 << 2)
- #define ME_ALL_EXTENTS_CLOSED_OPEN (3 << 2)
- #define ME_ALL_EXTENTS_OPEN_CLOSED (4 << 2)
- #define ME_ALL_EXTENTS_MASK (7 << 2)
- #define ME_START_IN_REGION (1 << 5)
- #define ME_END_IN_REGION (2 << 5)
- #define ME_START_AND_END_IN_REGION (3 << 5)
- #define ME_START_OR_END_IN_REGION (4 << 5)
- #define ME_IN_REGION_MASK (7 << 5)
- #define ME_NEGATE_IN_REGION (1 << 8)
- /* the following flags are internal-only */
- #define ME_INCLUDE_INTERNAL (1 << 9)
- #define ME_MIGHT_THROW (1 << 10)
- #define ME_MIGHT_MODIFY_TEXT (1 << 11)
- #define ME_MIGHT_MODIFY_EXTENTS (1 << 12)
- #define ME_MIGHT_MOVE_SOE (1 << 13)
- #define ME_MIGHT_CALL_ELISP (ME_MIGHT_THROW | ME_MIGHT_MODIFY_TEXT | \
- ME_MIGHT_MODIFY_EXTENTS | ME_MIGHT_MOVE_SOE)
-
-
- struct extent_replica
- {
- struct lrecord_header lheader;
-
- Bufpos start;
- Bufpos end;
- Lisp_Object object; /* An extent, normally */
- /* "dead" extent_replicas have EQ (object, Vthis_is_a_dead_extent_replica)
- */
- };
-
- DECLARE_LRECORD (extent_replica, struct extent_replica);
- #define XEXTENT_REPLICA(x) XRECORD (x, extent_replica, struct extent_replica)
- #define XSETEXTENT_REPLICA(x, p) XSETRECORD (x, p, extent_replica)
- #define EXTENT_REPLICAP(x) RECORDP (x, extent_replica)
- #define CHECK_EXTENT_REPLICA(x, i) CHECK_RECORD (x, extent_replica)
-
- #define extent_replica_extent(e) ((e)->object)
- #define extent_replica_start(e) ((e)->start)
- #define extent_replica_end(e) ((e)->end)
- #define set_extent_replica_start(e, pos) do { (e)->start = (int) (pos); } while (0)
- #define set_extent_replica_end(e, pos) do { (e)->end = (int) (pos); } while (0)
-
- extern Lisp_Object Vthis_is_a_dead_extent_replica;
-
- typedef struct extent_replica *EXTENT_REPLICA;
-
- #define EXTENT_LIVE_P(e) (!EQ (extent_object (e), Qt))
- #define EXTENT_REPLICA_LIVE_P(x) \
- (!EQ ((x)->object, Vthis_is_a_dead_extent_replica))
-
- #define CHECK_LIVE_EXTENT(x, i) \
- do { CHECK_EXTENT (x, i); \
- if (!EXTENT_LIVE_P (XEXTENT (x))) \
- x = wrong_type_argument (Qextent_live_p, (x)); } while (0)
-
- #define CHECK_LIVE_EXTENT_REPLICA(x, i) \
- do { CHECK_EXTENT_REPLICA (x, i); \
- if (!EXTENT_REPLICA_LIVE_P (XEXTENT_REPLICA (x))) \
- x = wrong_type_argument (Qextent_replica_live_p, (x)); } while (0)
-
- extern Lisp_Object Qextent_live_p, Qextent_replica_live_p;
-
- /* used in concat() and merge_replicas() */
- struct merge_replicas_struct
- {
- Lisp_Object dup_list;
- Charcount entry_offset;
- Charcount entry_length;
- };
-
- extern int inside_undo;
-
- extern struct extent_fragment *extent_fragment_new (struct buffer *buf,
- struct frame *frm);
- extern face_index extent_fragment_update (struct window *w,
- struct extent_fragment *ef,
- Bytind pos);
- extern void extent_fragment_delete (struct extent_fragment *ef);
-
- typedef int (*emf)(EXTENT extent, void *arg);
-
- extern Lisp_Object Vlast_highlighted_extent;
-
-
- #ifdef emacs /* things other than emacs want the structs */
-
- /* from alloc.c */
- extern struct extent *make_extent (void);
- extern struct extent_replica *make_extent_replica (Lisp_Object extent,
- Bufpos start,
- Bufpos end);
-
- /* from extents.c */
- extern EXTENT extent_ancestor_1 (EXTENT e);
- void allocate_extent_aux_struct (EXTENT ext);
- extern void mark_buffer_extents (struct buffer *buf,
- void (*markobj) (Lisp_Object));
- extern void init_buffer_extents (struct buffer *b);
- extern void uninit_buffer_extents (struct buffer *b);
- extern void map_extents (Bufpos from, Bufpos to, emf fn,
- void *arg, Lisp_Object obj, EXTENT after,
- unsigned int flags);
-
- extern void adjust_extents (struct buffer *buf, Memind from,
- Memind to, int amount);
- extern void adjust_extents_for_deletion (struct buffer *buf, Bytind from,
- Bytind to, int gapsize,
- int numdel);
- extern void verify_extent_modification (struct buffer *buf, Bytind from,
- Bytind to);
- extern void process_extents_for_insertion (struct buffer *buf,
- Bytind opoint, int length);
- extern void process_extents_for_deletion (struct buffer *buf, Bytind from,
- Bytind to, int destroy_them);
-
- extern Lisp_Object extent_getf (EXTENT extent, Lisp_Object property);
- extern void extent_putf (EXTENT extent, Lisp_Object property,
- Lisp_Object value);
- extern void set_extent_glyph (EXTENT extent, Lisp_Object glyph, int endp,
- unsigned int layout);
- extern void set_extent_face (EXTENT extent, Lisp_Object face);
-
- extern Lisp_Object replicate_extents (struct buffer *buf, Bufpos opoint,
- Charcount length);
- extern void splice_in_extent_replicas (struct buffer *buf, Bufpos opoint,
- Charcount length, Charcount pos,
- Lisp_Object dup_list);
- extern Lisp_Object merge_replicas (int number_of_lists,
- struct merge_replicas_struct *vec);
- extern Lisp_Object shift_replicas (Lisp_Object dup_list, int offset,
- int length);
-
- #ifdef ERROR_CHECK_EXTENTS
- extern void sledgehammer_extent_check (Lisp_Object obj);
- #endif
- #endif /* emacs */
-
- #endif /* _XEMACS_EXTENTS_H_ */
-